const path = require('path'); // nodejs核心模块, 专门处理路径问题
const ESLintPlugin = require('eslint-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const os = require('os');

// cpu核数
const threads = os.cpus().length;

module.exports = {
  // 入口
  entry: './src/main.js',
  // entry: {
  //   app: './src/app.js',
  //   main: './src/main.js'
  // },
  // 输出
  output: {
    // 开发环境没有输入文件
    path: undefined,
    // 入口文件打包后的文件名(文件位置&文件名)
    filename: 'static/js/main.js', // 打包后的文件名
    // filename: '[name].js'
    // clean: true, // 自动清空上次打包结果, 原理是将path整个目录清空,在进行打包
  },
  // 加载器
  module: {
    rules: [
      {
        // 每个文件只能被一个loader处理, 提高打包速度, 避免重复处理
        oneOf: [
          {
            test: /\.css$/i,
            use: [
              // 执行顺序, 从右向左, 从下向上
              'style-loader', // 将js中的css通过创建script标签的形式添加到html中让样式生效
              'css-loader' // 将css资源编译成commonjs的模块到js中
            ],
          },
          {
            test: /\.less$/i,
            // loader: 'xxx', // 只能使用一个loader
            use: [
              // compiles Less to CSS
              'style-loader',
              'css-loader',
              'less-loader', // 将less编译成css
            ],
          },
          {
            test: /\.s[ac]ss$/i,
            use: [
              // 将 JS 字符串生成为 style 节点
              'style-loader',
              // 将 CSS 转化成 CommonJS 模块
              'css-loader',
              // 将 Sass 编译成 CSS
              'sass-loader',
            ],
          },
          {
            test: /\.styl$/,
            // loader: 'stylus-loader', // 将 Stylus 文件编译为 CSS
            use: [
              // 将 JS 字符串生成为 style 节点
              'style-loader',
              // 将 CSS 转化成 CommonJS 模块
              'css-loader',
              // 将 stylus 编译成 CSS
              'stylus-loader',
            ],
          },
          // { // 处理图片资源 webpack5 已经内置
          //   test: /\.(png|jpe?g|gif|webp)$/,
          //   type: "asset",
          // },
          {
            test: /\.(png|jpe?g|gif|svg|webp)$/,
            type: 'asset', // asset 会转base64格式
            parser: {
              dataUrlCondition: { // 匹配的资源图片大小如果小于下面的配置会自动转为base64格式,减少请求
                maxSize: 50 * 1024 // 50kb
              }
            },
            generator: { 
              // 静态资源存放目录
              // hash:10 文件哈希值只要10位
              filename: 'static/images/[hash:10][ext][query]'
            }
          },
          { // 处理字体图标&视频&音频等
            test: /\.(ttf|woff2?|mp3|mp4|avi)$/,
            type: 'asset/resource',
            generator: { 
              // 静态资源存放目录
              // hash:10 文件哈希值只要10位
              filename: 'static/media/[hash:10][ext][query]'
            }
          },
          {
            test: /\.js$/,
            // exclude: /node_modules/, // 要排除的文件, 排除node_modules文件中的js文件(不处理) 
            include: path.resolve(__dirname, '../src'), // 只处理src目录下的js文件
            use:[
              {
                loader: 'thread-loader', // 开启多线程
                options: {
                  works: threads, // 线程数量
                }
              },
              {
                loader: 'babel-loader', // es6转es5
                options: {
                  // presets: ['@babel/preset-env'], // 可在这个地方写, 也可以在项目根目录创建babel.config.js文件来写
                  cacheDirectory: true, // 开启babel缓存
                  cacheCompression: false, // 关闭缓存文件压缩
                  plugins: ["@babel/plugin-transform-runtime"], // 减少代码体积
                },
              }
            ]
          },
        ]
      }
    ]
  },
  // 插件
  plugins: [
    new ESLintPlugin({
      // context 只检测当前目录下的src文件下的文件
      context: path.resolve(__dirname, '../src'),
      exclude: 'node_modules', // 不检测node_modules目录下的文件(默认值:node_modules)
      threads, // 开启多线程和进程数量
    }),
    new HtmlWebpackPlugin({
      // 以public/index.html文件下的index.html为模板创建新的HTML文件, 会保存index.html文件的内容
      template: path.resolve(__dirname, '../public/index.html')
    })
  ],
  devServer: {
    host: 'localhost', // 打开的域名
    port: 3000, // 3000端口
    open: true, // 自动打开浏览器
    hot: true, // 开启HMR功能（只能用于开发环境，生产环境不需要了, 默认true）
  },
  // 模式
  mode: 'development',
  devtool: 'cheap-module-source-map', // 构建代码映射
};
